﻿using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;

namespace ContaPlanner.Models
{
    public enum Frecuencia
    {
        [Description("Frecuencia mensual")]
        Mensual
    };

    public enum TipoImporte
    {
        [Description("Importe fijo")]
        Fijo,
        [Description("Importe igual a recibo anterior")]
        Anterior,
        [Description("Importe igual a la media de recibos anteriores")]
        Media,
        [Description("Importe igual que el equivalente anterior")]
        Equivalente

    };

    public enum TipoDiaMes
    {
        [Description("Día fija")]
        Fijo,
        [Description("Día igual a recibo anterior")]
        Anterior
    };

    public enum DiaMesLaboral
    {
        [Description("No mover si no es día laboral")]
        NoMover,
        [Description("Mover a día antes si no es día laboral")]
        MoverAntes,
        [Description("Mover a día después si no es día laboral")]
        MoverDespues
    };

    [Table("Recibos")]
    public class Recibo
    {
        [Key]
        public int ReciboId { get; set; }
        public Frecuencia Frecuencia { get; set; }
        public decimal Importe { get; set; }
        public TipoImporte TipoImporte { get; set; }
        public int DiaMes { get; set; }
        public DiaMesLaboral DiaMesLaboral { get; set; }
        public TipoDiaMes TipoDiaMes { get; set; }
        public int RecibosMedia { get; set; }
        public virtual Cuenta Origen { get; set; }
        public virtual Cuenta Destino { get; set; }

        public Movimiento GetNextMovimiento(Cuenta cuenta, DateTime apartir)
        {
            if (DiaMes < apartir.Day) apartir = apartir.AddMonths(1);
            var anyo = apartir.Year;
            var mes = apartir.Month;
            var dia = DiaMes;
            var otracuenta = cuenta.CuentaId == Origen.CuentaId ? Destino : Origen;
            var ultimo = cuenta.LastAsiento(otracuenta, apartir);
            if (TipoDiaMes == TipoDiaMes.Anterior)
            {
                if (ultimo != null) dia = ultimo.Fecha.Day;
            }
            var fecha = new DateTime(anyo, mes, dia);
            if (DiaMesLaboral == DiaMesLaboral.MoverAntes)
            {
                while (!fecha.IsLaboral()) fecha = fecha.AddDays(-1);
            }
            if (DiaMesLaboral == DiaMesLaboral.MoverDespues)
            {
                while (!fecha.IsLaboral()) fecha = fecha.AddDays(1);
            }
            var importe = Importe;
            if (TipoImporte == TipoImporte.Anterior)
            {
                if (ultimo != null) importe = ultimo.Importe;
            }
            if (TipoImporte == TipoImporte.Media)
            {
                var ultimos = cuenta.LastAsientos(otracuenta, apartir, RecibosMedia);
                if (ultimos.Any()) importe = Math.Round(ultimos.Average(a => a.Importe), 2);
            }
            if (TipoImporte == TipoImporte.Equivalente)
            {
                var equivalente = cuenta.LastAsiento(otracuenta, apartir.AddYears(-1));
                if (equivalente != null) importe = equivalente.Importe;
            }
            return new Movimiento
            {
                Fecha = fecha, 
                OtraCuenta = otracuenta,
                OtraUbicacion = null,
                ImporteMas = cuenta.CuentaId == Origen.CuentaId ? 0 : importe,
                ImporteMenos = cuenta.CuentaId == Origen.CuentaId ? importe : 0,
                Saldo = 0
            };
        }
    }
}
